import { CardUsingEventHandler, EmptyCardUsingEventHandler } from "@/core/playersystem/handlers";
import { Card, Color, Equipment, BrilliantCard, BasicCard, HurtType } from "../card";
import { Player } from "@/core/playersystem/player";
import { DefaultPromise } from "@/core/util/common";
import { Weapons } from "../equipments/weapons";
import { Sha, Shan } from "../basicCard";
import { DelayBrilliantness } from "./delay";
import { PickPurpose } from "@/core/strategies/BaseSmartBehavior";
import { GameManager } from "@/core/gamesystem/gameManager";

/**
 * 非延迟类
 */
export class NoDelayBrilliantness extends BrilliantCard {

    async use(): Promise<void> {
        if (this.cardProperties.owner) {
            if (!this.cardProperties.source) {
                this.cardProperties.source = this.cardProperties.owner
            }
            const handler = this.createCardUsingEventHandler(this, this.cardProperties.source)
            const gm = this.cardProperties.source.gameManager

            if (!this.cardProperties.target) {
                await this.waitforSpecTarget(this.cardProperties.source)
            }

            // 卡牌使用事件
            await handler.startCardUse()

            if (this.cardProperties.target) {
                const players = gm.presentPlayer()

                let requestWuxieHandler = handler

                for (const player of players) {
                    // 允许所有人响应无懈 TODO 当前版本还是仅考虑目标对象使用无懈
                    requestWuxieHandler = player.createCardUsingEventHandler(requestWuxieHandler)
                }

                this.cardProperties.source.handCardAreas.dropCard(this)
                this.appendDeskCard(gm)
                // 指定玩家后事件
                await this.afterSpecTargetUsing(requestWuxieHandler, handler);

                await handler.afterUsing()

            }
        }
    }

    appendDeskCard(gm: GameManager) {
        gm.appendDeskCard(this)
    }

    private async afterSpecTargetUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        await requestWuxieHandler.specTarget();

        if (!this.cardProperties.cancelEffect) {
            // TODO 无懈可击响应逻辑, 等待响应事件
            const respResult = await requestWuxieHandler.needAndWaitForResponse(WuXieKeJi);

            await requestWuxieHandler.afterResponse(respResult.selectedCards, respResult.cancel);

            if (!this.cardProperties.cancelEffect) {
                await this.afterWuXieResponseUsing(requestWuxieHandler, sourceHandler);
            }
        }
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if (this.cardProperties.target) {
            const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
            // 不涉及伤害的结算
            await handler.settleHurt(0);

            await handler.afterSettle();
        }
        
    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        return new EmptyCardUsingEventHandler(card, player)
    }

    async waitforSpecTarget(source: Player): Promise<void> {
        
    }

}

/**
 * 过河拆桥
 */
export class GuoHeChaiQiao extends NoDelayBrilliantness {

    targetCard: Card | null = null

    async waitforSpecTarget(source: Player): Promise<void> {
        let targetPlayer = this.cardProperties.target
        const gm = source.gameManager
        // 如果目标已经被指定了就不用再选玩家了
        if (targetPlayer == null) {
            const maxdistance = this.specDistance(source)
            const canPickPlayers = gm.distanceN(maxdistance)
            const pickNumber = 1
            gm.appendLog(`${source.name} 打出了${this.colorCN()}${this.numberCN()}${this.info()} 请选择需要拆的玩家`)
            const options = {canPickPlayers, canPickMin: pickNumber, canPickMax: pickNumber, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)
            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                targetPlayer = null
            } else {
                targetPlayer = pickResult.selectedPlayers[0]
            }
        }


        if (targetPlayer && targetPlayer.hasCards()) {
            // 指定目标对象 目标对象有牌
            this.cardProperties.target = targetPlayer
            // TODO 待延迟性锦囊实现后设为可指定
            if (targetPlayer.hasCards(Equipment.name) || targetPlayer.hasCards(DelayBrilliantness.name)) {
                // 有装备牌
                gm.appendLog('请选择需要拆的手牌/装备牌/延迟性锦囊牌TODO,默认手牌')
                const options = {player: targetPlayer, canPickMin: 1, canPickMax: 1, currentPlayer: source}
                const selectedCardResult = await source.behaviorStragy.waitForPickAllTypeCard(options)
                if (selectedCardResult.cancel || selectedCardResult.selectedCards.length < 1) {
                    // 有手牌就设为null,没手牌就按序选一张装备牌
                    this.targetCard = targetPlayer.hasCards(BasicCard.name) ? null : targetPlayer.equipmentAreas.randSelectEquipment()
                } else {
                    this.targetCard = selectedCardResult.selectedCards[0]
                }
            } else {
                // 有手牌,默认手牌,手牌先设为null 考虑期间无懈的使用 待结算时再确定最后的手牌
                this.targetCard = null
            }

            const thisCardInfo = this.colorCN() + this.numberCN() + this.info()
            const targetCardInfo = this.targetCard instanceof Equipment ? this.targetCard.colorCN() + this.targetCard.numberCN() + this.targetCard.info() : '手牌'
            gm.appendLog(`${source.name} 对目标 ${this.cardProperties.target.name} 使用了 ${thisCardInfo} 的 ${targetCardInfo},等待目标响应...`)
        }
    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseGuohechaiqiaoHandler extends EmptyCardUsingEventHandler<this> {
            async settleHurt(n: number): Promise<void> {
                const sourceCard = this.card
                const target = sourceCard.cardProperties.target
                const sourcePlayer = sourceCard.cardProperties.source
                if (sourcePlayer && target && sourceCard instanceof GuoHeChaiQiao) {
                    let targetCard = sourceCard.targetCard
                    const gm = target.gameManager
                    if (targetCard != null) {
                        // 装备牌或延迟类锦囊牌
                    } else if (target.handCardAreas.hasHandCards()) {
                        // 有手牌选手牌
                        targetCard = target.handCardAreas.peekHandCard()
                    } else if (target.hasCards(Equipment.name)) {
                        // 没手牌但有装备牌,要重新选
                        gm.appendLog('对方已经没有手牌了,您可重新选一张牌...')
                        await sourceCard.waitforSpecTarget(sourcePlayer)
                        targetCard = sourceCard.targetCard
                    } else {
                        // 啥都没了那就没了
                        gm.appendLog('对方已经没有牌可拆了...')
                        return super.settleHurt(n)
                    }

                    if (targetCard != null) {
                        const targetCardInfo = targetCard.colorCN() + targetCard.numberCN() + targetCard.info()
                        gm.appendLog(`${sourcePlayer.name} 过拆了 ${target.name} 一张 ${targetCardInfo}`)
                        target.handCardAreas.dropCard(targetCard)
                        gm.defineDeskCard(target.name, targetCardInfo, '被拆')
                        targetCard.onDrop()

                    }
                    
                }

                return super.settleHurt(n)
            }

            afterUsing(): Promise<void> {
                const sourceCard = this.card
                sourceCard.targetCard = null
                sourceCard.onDrop()
                return super.afterUsing()
            }
        }
        return new BaseGuohechaiqiaoHandler(card, player)

    }

    info(): string {
        return "过河拆桥"
    }
}

/**
 * 顺手牵羊
 */
export class ShunShouQianYang extends NoDelayBrilliantness {
    targetCard: Card | null = null

    async waitforSpecTarget(source: Player): Promise<void> {
        let targetPlayer = this.cardProperties.target
        const gm = source.gameManager
        // 如果目标已经被指定了就不用再选玩家了
        if (targetPlayer == null) {
            const maxdistance = this.specDistance(source)
            const canPickPlayers = gm.distanceN(maxdistance)
            const pickNumber = 1
            gm.appendLog(`${source.name} 打出了${this.colorCN()}${this.numberCN()}${this.info()} 请选择需要顺的玩家`)
            const options = {canPickPlayers, canPickMin: pickNumber, canPickMax: pickNumber, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)
            
            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                targetPlayer = null
            } else {
                targetPlayer = pickResult.selectedPlayers[0]
            }
        }
        

        if (targetPlayer && targetPlayer.hasCards()) {
            // 指定目标对象
            this.cardProperties.target = targetPlayer
            // TODO 待延迟性锦囊实现后设为可指定
            if (targetPlayer.hasCards(Equipment.name)) {
                gm.appendLog('请选择需要顺的手牌/装备牌/延迟性锦囊牌TODO,默认手牌')
                const options = {player: targetPlayer, canPickMin: 1, canPickMax: 1, currentPlayer: source}
                const selectedCardResult = await source.behaviorStragy.waitForPickAllTypeCard(options)
                if (selectedCardResult.cancel || selectedCardResult.selectedCards.length < 1) {
                    // 有手牌就设为null,没手牌就按序选一张装备牌
                    this.targetCard = targetPlayer.hasCards(BasicCard.name) ? null : targetPlayer.equipmentAreas.randSelectEquipment()
                } else {
                    this.targetCard = selectedCardResult.selectedCards[0]
                }
            } else {
                this.targetCard = null
            }

            const thisCardInfo = this.colorCN() + this.numberCN() + this.info()
            const targetCardInfo = this.targetCard instanceof Equipment && this.targetCard.hasEquip() ? this.targetCard.colorCN() + this.targetCard.numberCN() + this.targetCard.info() : '手牌'
            gm.appendLog(`${source.name} 对目标 ${this.cardProperties.target.name} 使用了 ${thisCardInfo} 的 ${targetCardInfo},等待目标响应...`)
        }
    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseShunshouqianyangHandler extends EmptyCardUsingEventHandler<this> {
            async settleHurt(n: number): Promise<void> {
                const sourceCard = this.card
                const target = sourceCard.cardProperties.target
                const sourcePlayer = sourceCard.cardProperties.source
                if (sourcePlayer && target && sourceCard instanceof ShunShouQianYang) {
                    let targetCard = sourceCard.targetCard
                    const gm = target.gameManager
                    let targetCardInfo = ''
                    if (targetCard != null) {
                        // 装备牌或延迟类锦囊牌
                        targetCardInfo = targetCard.colorCN() + targetCard.numberCN() + targetCard.info()
                    } else if (target.handCardAreas.hasHandCards()) {
                        // 有手牌选手牌
                        targetCard = target.handCardAreas.peekHandCard()
                        targetCardInfo = '手牌'
                    } else if (target.hasCards(Equipment.name)) {
                        // 没手牌但有装备牌,要重新选
                        gm.appendLog('对方已经没有手牌了,您可重新选一张牌...')
                        await sourceCard.waitforSpecTarget(sourcePlayer)
                        targetCard = sourceCard.targetCard
                        if (targetCard != null) {
                            targetCardInfo = targetCard.colorCN() + targetCard.numberCN() + targetCard.info()
                        }
                    } else {
                        // 啥都没了那就没了
                        gm.appendLog('对方已经没有牌可顺了...')
                        return super.settleHurt(n)
                    }

                    if (targetCard != null) {
                        gm.appendLog(`${sourcePlayer.name} 拿到了 ${target.name} 一张 ${targetCardInfo}`)
                        target.handCardAreas.dropCard(targetCard)
                        targetCard.cardProperties.reuse = true
                        targetCard.onDrop()
                        sourcePlayer.handCardAreas.acquireHandCard(targetCard)
                    }
                }

                return super.settleHurt(n)
            }

            afterUsing(): Promise<void> {
                const sourceCard = this.card
                sourceCard.targetCard = null
                sourceCard.onDrop()
                return super.afterUsing()
            }
        }
        return new BaseShunshouqianyangHandler(card, player)
    }

    
    specDistance(player: Player): number {
        return 1
    }

    canuse(): boolean {
        if (this.cardProperties.owner) {
            const owner = this.cardProperties.owner
            const gm = owner.gameManager
            const maxdistance = this.specDistance(owner)
            const canPickPlayers = gm.distanceN(maxdistance)
            return canPickPlayers.length > 0
        }
        return false
    }

    info(): string {
        return "顺手牵羊"
    }
}

/**
 * 无懈可击
 */
export class WuXieKeJi extends NoDelayBrilliantness {

    targetCard: Card | null = null

    async response(sourceCard: Card): Promise<Card> {
        if (this.cardProperties.owner && sourceCard.cardProperties.source) {
            this.cardProperties.source = this.cardProperties.owner
            this.cardProperties.target = sourceCard.cardProperties.source
            if (sourceCard instanceof WuXieKeJi && sourceCard.targetCard) {
                this.targetCard = sourceCard.targetCard
            } else {
                this.targetCard = sourceCard
            }
            const gm = this.cardProperties.owner.gameManager
            const thisCardInfo = this.colorCN() + this.numberCN() + this.info()
            const sourceCardInfo = sourceCard.colorCN() + sourceCard.numberCN() + sourceCard.info()
            gm.appendLog(`${this.cardProperties.source.name} 使用了 ${thisCardInfo} 企图抵消 ${this.cardProperties.target.name} 的 ${sourceCardInfo}`)

            const proxyCard = this.cardProperties.source.handCardAreas.useCard(this)
            await proxyCard.use()
            
            if (!this.cardProperties.cancelEffect) {
                sourceCard.cardProperties.cancelEffect = true
                const sourceCardInfo = sourceCard.colorCN() + sourceCard.numberCN() + sourceCard.info()
                gm.appendLog(`${sourceCard.cardProperties.source.name} 的 ${sourceCardInfo} 被抵消无效`)
            }

        }

        return super.response(sourceCard)
    }

    canuse(): boolean {
        return false
    }

    info(): string {
        return "无懈可击"
    }
}

/**
 * 火攻
 */
export class HuoGong extends NoDelayBrilliantness {

    async waitforSpecTarget(source: Player): Promise<void> {
        let targetPlayer = this.cardProperties.target
        const gm = source.gameManager
        // 如果目标已经被指定了就不用再选玩家了
        if (targetPlayer == null) {
            const maxdistance = this.specDistance(source)
            let canPickPlayers = gm.presentPlayer()
            // TODO 目标指定过滤器
            canPickPlayers = canPickPlayers.filter(p => p.hasCards(BasicCard.name))
            const pickNumber = 1
            gm.appendLog(`${source.name} 打出了${this.colorCN()}${this.numberCN()}${this.info()} 请选择需要火攻的玩家`)
            const options = {canPickPlayers, canPickMin: pickNumber, canPickMax: pickNumber, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)
            
            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                targetPlayer = null
            } else {
                targetPlayer = pickResult.selectedPlayers[0]
            }
        }
        

        if (targetPlayer && targetPlayer.hasCards(BasicCard.name)) {
            // 指定目标对象
            this.cardProperties.target = targetPlayer

            const thisCardInfo = this.colorCN() + this.numberCN() + this.info()
            gm.appendLog(`${source.name} 对目标 ${this.cardProperties.target.name} 使用了 ${thisCardInfo},等待目标响应...`)
        }
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if (this.cardProperties.target) {
            const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
            const gm = this.cardProperties.target.gameManager
            const targetHandCards = this.cardProperties.target.handCardAreas.handCards

            const pickone = await handler.pickAnyOne(targetHandCards)
            if (pickone.isPresent()) {
                const showone = pickone.get()
                const showCardInfo = showone.colorCN() + showone.numberCN() + showone.info()
                gm.appendLog('对方被火攻展示的手牌为:' + showCardInfo + '请选择需要火攻造成伤害的牌,不需要请点取消')
                gm.defineDeskCard('火攻展示', showCardInfo, this.cardProperties.target.name)

                const showColor = showone.color
                if (this.cardProperties.source) {
                    const thisHandCards = this.cardProperties.source.handCardAreas.handCards
                    const canPickCards = thisHandCards.filter((t) => t.color === showColor)
                    if (canPickCards.length > 0) {
                        const [canPickMin, canPickMax] = [1,1]
                        const pickPurpose = PickPurpose.DROPPING
                        const currentPlayer = this.cardProperties.source
                        const options = {canPickCards, canPickMin, canPickMax, pickPurpose, currentPlayer}
                        const pickResult = await currentPlayer.behaviorStragy.waitForPickCard(options)
                        if (!pickResult.cancel && pickResult.selectedCards.length > 0) {
                            const pickCard = pickResult.selectedCards[0]
                            this.cardProperties.source.handCardAreas.dropCard(pickCard)
                            pickCard.onDrop()
                            const pickCardInfo = pickCard.colorCN() + pickCard.numberCN() + pickCard.info()
                            gm.defineDeskCard('火攻弃牌', pickCardInfo, this.cardProperties.source.name)

                            // 确认丢牌造成伤害,进入伤害结算流程
                            const hurtCount = await handler.calHurt()

                            await handler.settleHurt(hurtCount)

                            gm.appendLog(`${this.cardProperties.source.name} 对 ${this.cardProperties.target.name} 使用火攻丢弃${pickCardInfo},造成 ${hurtCount} 点伤害`)

                            await handler.playerBeingDead()

                            await handler.afterSettle()
                        } else {
                            gm.appendLog('你取消火攻伤害牌')
                        }

                    } else {
                        gm.appendLog('你没有可以火攻造成伤害的牌')
                    }

                }
            } else {
                gm.appendLog('对方已经没有手牌可展示了')
            }

        }
    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseHuoGongHandler extends EmptyCardUsingEventHandler<this> {
            calHurt(): Promise<number> {
                return DefaultPromise(1)
            }

            settleHurt(n: number): Promise<void> {
                if (!this.card.cardProperties.target || !this.card.cardProperties.source || !this.card.cardProperties.owner) {
                    return super.settleHurt(n)
                }

                if (!this.card.cardProperties.cancelEffect) {
                    this.card.cardProperties.target.reduceHP(n)
                }
                return super.settleHurt(n)
            }

            afterUsing(): Promise<void> {
                const sourceCard = this.card
                sourceCard.onDrop()
                return super.afterUsing()
            }
        }

        return new BaseHuoGongHandler(card, player)
    }

    hurtType(): HurtType {
        return HurtType.FIRE
    }

    info(): string {
        return "火攻"
    }

}

/**
 * 借刀杀人
 */
export class JieDaoShaRen extends NoDelayBrilliantness {

    target2: Player|null = null

    async waitforSpecTarget(source: Player): Promise<void> {
        let targetPlayer = this.cardProperties.target
        const gm = source.gameManager
        if (targetPlayer == null) {
            const maxdistance = this.specDistance(source)
            let canPickPlayers = gm.distanceN(maxdistance)
            canPickPlayers = canPickPlayers.filter(p => p.equipmentAreas.hasWeapon())
            const pickNumber = 1
            gm.appendLog(`${source.name} 打出了${this.colorCN()}${this.numberCN()}${this.info()} 请选择需要借刀的玩家`)
            const options = {canPickPlayers, canPickMin: pickNumber, canPickMax: pickNumber, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)

            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                targetPlayer = null
            } else {
                targetPlayer = pickResult.selectedPlayers[0]
            }
        }

        if (targetPlayer && targetPlayer.equipmentAreas.hasWeapon()) {
            const canPickPlayers = gm.playerDistanceN(targetPlayer, targetPlayer.calAttackDist())
            const pickNumber = 1
            gm.appendLog(`${source.name} 对 ${targetPlayer.name} 打出了${this.colorCN()}${this.numberCN()}${this.info()} 请选择需要借刀杀的玩家`)
            const options = {canPickPlayers, canPickMin: pickNumber, canPickMax: pickNumber, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)
            if (!pickResult.cancel && pickResult.selectedPlayers.length > 0) {
                this.cardProperties.target = targetPlayer
                this.target2 = pickResult.selectedPlayers[0]
            }
        }
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
    
    if (this.cardProperties.target && this.target2 && this.cardProperties.source) {
        const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
        // 目标需要出杀 TODO 控制是否由 needAndWaitForResponse调用response
        const respResult = await handler.needAndWaitForResponse(Sha);
        if (!respResult.cancel && respResult.selectedCards.length > 0) {
            // 出杀,使用杀的逻辑
            const respCard = respResult.selectedCards[0]
            // 指定源和目标
            respCard.cardProperties.owner = this.cardProperties.target // 响应之后默认是没有owner的 这里给他个owner
            respCard.cardProperties.target = this.target2
            respCard.cardProperties.reuse = true
            const proxyCard = this.cardProperties.target.handCardAreas.useCard(respCard)
            // 目前交互下 使用杀无法使用需确认性的武器效果(贯石斧,青龙刀等青钢剑不影响),需手动取消 TODO 待引入决策系统后实现
            await proxyCard.use()
        } else {
            // 没有杀,获得其武器
            const weapon = this.cardProperties.target.equipmentAreas.getWeapon()
            if (weapon) {
                const gm = this.cardProperties.source.gameManager
                gm.appendLog('对方无法出杀,你获得其武器')
                weapon.cardProperties.reuse = true
                weapon.onDrop()
                this.cardProperties.source.handCardAreas.acquireHandCard(weapon)
            }
        }
        this.onDrop()

    }
    }

    canuse(): boolean {
        if (this.cardProperties.owner) {
            const owner = this.cardProperties.owner
            const gm = owner.gameManager
            const maxdistance = this.specDistance(owner)
            let canPickPlayers = gm.distanceN(maxdistance)
            canPickPlayers = canPickPlayers.filter(p => p.equipmentAreas.hasWeapon())
            return canPickPlayers.length > 0
        }
        return false
    }

    info(): string {
        return "借刀杀人"
    }


}

/**
 * 决斗
 */
export class JueDou extends NoDelayBrilliantness {

    async waitforSpecTarget(source: Player): Promise<void> {
        let targetPlayer = this.cardProperties.target
        const gm = source.gameManager
        if (targetPlayer == null) {
            const canPickPlayers = gm.exceptCurrent()
            const pickNumber = 1
            gm.appendLog(`${source.name} 打出了${this.colorCN()}${this.numberCN()}${this.info()} 请选择需要决斗的玩家`)
            const options = {canPickPlayers, canPickMin: pickNumber, canPickMax: pickNumber, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)

            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                targetPlayer = null
            } else {
                targetPlayer = pickResult.selectedPlayers[0]
                this.cardProperties.target = targetPlayer
            }
        }
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if (this.cardProperties.target && this.cardProperties.source) {
            const realTarget = this.cardProperties.target
            const realSource = this.cardProperties.source
            let trunRealTarget = true
            let cancel = false
            const gm = realSource.gameManager
            while (!cancel) {
                // TODO 这样改变taget是不好的行为??
                this.cardProperties.target = trunRealTarget ? realTarget : realSource
                // 不断决斗轮询出杀
                const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
                
                const respResult = await handler.needAndWaitForResponse(Sha)
                cancel = respResult.cancel || respResult.selectedCards.length < 1
                if (!cancel) {
                    const respCard = respResult.selectedCards[0]
                    const respCardInfo = respCard.colorCN() + respCard.numberCN() + respCard.info()
                    gm.appendLog(this.cardProperties.target.name + '被决斗打出一张' + respCardInfo)
                    trunRealTarget = !trunRealTarget
                }
            }
            // this.target 无法响应,进入伤害结算流程
            const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)

            const hurtCount = await handler.calHurt()

            await handler.settleHurt(hurtCount)

            gm.appendLog(`${realSource.name} 对 ${realTarget.name} 决斗 ${this.cardProperties.target.equals(realTarget)?'胜利':'失败'} ,对${this.cardProperties.target.name}造成 ${hurtCount} 点伤害`)

            await handler.playerBeingDead()

            await handler.afterSettle()

            this.onDrop()
            
        }
    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseJudDouHandler extends EmptyCardUsingEventHandler<this> {
            calHurt(): Promise<number> {
                return DefaultPromise(1)
            }

            settleHurt(n: number): Promise<void> {
                if (!this.card.cardProperties.target || !this.card.cardProperties.source || !this.card.cardProperties.owner) {
                    return super.settleHurt(n)
                }

                if (!this.card.cardProperties.cancelEffect) {
                    this.card.cardProperties.target.reduceHP(n)
                }
                return super.settleHurt(n)
            }
        }

        return new BaseJudDouHandler(card, player)
    }

    info(): string {
        return "决斗"
    }
}

/**
 * 无中生有
 */
export class WuZhongShengYou extends NoDelayBrilliantness {

    async waitforSpecTarget(source: Player): Promise<void> {
        // 直接对自己使用
        this.cardProperties.target = source
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if(this.cardProperties.source && this.cardProperties.target) {
            const gm = this.cardProperties.source.gameManager
            const cardHeap = gm.cardHeap
            let card = cardHeap.drawACard()
            if(card) {
                this.cardProperties.source.handCardAreas.acquireHandCard(card)
            }
            card = cardHeap.drawACard()
            if(card) {
                this.cardProperties.source.handCardAreas.acquireHandCard(card)
            }
            gm.appendLog(this.cardProperties.source.name + '使用无中生有获得两张牌')
            this.onDrop()
        }
    }

    info(): string {
        return "无中生有"
    }
}

/**
 * 铁索连环
 */
export class TieSuoLianHuan extends NoDelayBrilliantness {

    async waitforSpecTarget(source: Player): Promise<void> {
        let targetPlayer = this.cardProperties.target
        const gm = source.gameManager
        // 如果目标已经被指定了就不用再选玩家了
        if (targetPlayer == null) {
            const canPickPlayers = gm.presentPlayer()
            gm.appendLog('请选择需要连环的玩家,取消为重铸(连环功能还没实现哦,不要选)')
            const options = {canPickPlayers: [], canPickMin: 1, canPickMax: 2, currentPlayer: source}
            const pickResult = await source.behaviorStragy.waitForPickPlayer(options)
            
            if (pickResult.cancel || pickResult.selectedPlayers.length < 1) {
                // 重铸
                source.handCardAreas.dropCard(this)
                gm.defineDeskCard('重铸', this.info(), source.name)
                this.onDrop()
                const newCard = gm.cardHeap.drawACard()
                if (newCard) {
                    source.handCardAreas.acquireHandCard(newCard)
                }
            } else {
                targetPlayer = pickResult.selectedPlayers[0]
                gm.appendLog('连环功能还没实现哦~~~~')
            }
        }
    }

    info(): string {
        return "铁索连环"
    }
}

/**
 * 南蛮入侵
 */
export class NanManRuQin extends NoDelayBrilliantness {

    targets: Player[] = []

    async use(): Promise<void> {
        if (this.cardProperties.owner) {
            const gm = this.cardProperties.owner.gameManager
            gm.appendLog(this.cardProperties.owner.name + '发起' + this.info())
            gm.defineDeskCard(this.cardProperties.owner.name, this.info(), '')
            this.targets = gm.exceptCurrent()
            for(const target of this.targets) {
                this.cardProperties.target = target
                this.cardProperties.cancelEffect = false
                await super.use()
            }
            this.targets = []
            this.onDrop()
        }

    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseNanManRuQinHandler extends EmptyCardUsingEventHandler<this> {
            calHurt(): Promise<number> {
                return DefaultPromise(1)
            }

            settleHurt(n: number): Promise<void> {
                if (!this.card.cardProperties.target || !this.card.cardProperties.source || !this.card.cardProperties.owner) {
                    return super.settleHurt(n)
                }

                if (!this.card.cardProperties.cancelEffect) {
                    this.card.cardProperties.target.reduceHP(n)
                }
                return super.settleHurt(n)
            }
        }

        return new BaseNanManRuQinHandler(card, player)
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if (this.cardProperties.target && this.cardProperties.source) {
            const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
            const gm = this.cardProperties.target.gameManager
            const respResult = await handler.needAndWaitForResponse(Sha)
            if (respResult.cancel || respResult.selectedCards.length < 1) {
                // 无法出杀,扣血
                const hurtCount = await handler.calHurt()

                await handler.settleHurt(hurtCount)

                gm.appendLog(`${this.cardProperties.source.name} 发动南蛮入侵对 ${this.cardProperties.target.name} 造成 ${hurtCount} 点伤害`)

                await handler.playerBeingDead()

                await handler.afterSettle()
            } else {
                const respCard = respResult.selectedCards[0]
                const respCardInfo = respCard.colorCN() + respCard.numberCN() + respCard.info()
                gm.appendLog(`${this.cardProperties.target.name} 对南蛮入侵响应一张 ${respCardInfo}`)

            }

        }
    }

    info(): string {
        return "南蛮入侵"
    }
}

/**
 * 万箭齐发
 */
export class WanJianQiFa extends NoDelayBrilliantness {

    targets: Player[] = []

    async use(): Promise<void> {
        if (this.cardProperties.owner) {
            const gm = this.cardProperties.owner.gameManager
            gm.appendLog(this.cardProperties.owner.name + '发起' + this.info())
            gm.defineDeskCard(this.cardProperties.owner.name, this.info(), '')
            this.targets = gm.exceptCurrent()
            for(const target of this.targets) {
                this.cardProperties.target = target
                this.cardProperties.cancelEffect = false
                await super.use()
            }
            this.targets = []
            this.onDrop()
        }

    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseWanJianQiFaHandler extends EmptyCardUsingEventHandler<this> {
            calHurt(): Promise<number> {
                return DefaultPromise(1)
            }

            settleHurt(n: number): Promise<void> {
                if (!this.card.cardProperties.target || !this.card.cardProperties.source || !this.card.cardProperties.owner) {
                    return super.settleHurt(n)
                }

                if (!this.card.cardProperties.cancelEffect) {
                    this.card.cardProperties.target.reduceHP(n)
                }
                return super.settleHurt(n)
            }
        }

        return new BaseWanJianQiFaHandler(card, player)
    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if (this.cardProperties.target && this.cardProperties.source) {
            const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
            const gm = this.cardProperties.target.gameManager
            const respResult = await handler.needAndWaitForResponse(Shan)
            if (respResult.cancel || respResult.selectedCards.length < 1) {
                // 无法响应,扣血
                const hurtCount = await handler.calHurt()

                await handler.settleHurt(hurtCount)

                gm.appendLog(`${this.cardProperties.source.name} 发动万箭齐发对 ${this.cardProperties.target.name} 造成 ${hurtCount} 点伤害`)

                await handler.playerBeingDead()

                await handler.afterSettle()
            } else {
                const respCard = respResult.selectedCards[0]
                const respCardInfo = respCard.colorCN() + respCard.numberCN() + respCard.info()
                gm.appendLog(`${this.cardProperties.target.name} 对万箭齐发响应一张 ${respCardInfo}`)

            }

        }
    }

    info(): string {
        return "万箭齐发"
    }
}

/**
 * 桃园结义
 */
export class TaoYuanJieYi extends NoDelayBrilliantness {
    targets: Player[] = []

    async use(): Promise<void> {
        if (this.cardProperties.owner) {
            const gm = this.cardProperties.owner.gameManager
            gm.appendLog(this.cardProperties.owner.name + '发起' + this.info())
            const thisCardInfo = this.colorCN() + this.numberCN() + this.info()
            gm.defineDeskCard(this.cardProperties.owner.name, thisCardInfo, '')
            this.targets = gm.presentPlayer()
            for(const target of this.targets) {
                this.cardProperties.target = target
                this.cardProperties.cancelEffect = false
                await super.use()
            }
            this.targets = []
            this.onDrop()
        }

    }

    appendDeskCard(gm: GameManager) {

    }

    createCardUsingEventHandler(card: this, player: Player): CardUsingEventHandler<this> {
        class BaseTaoYuanJieYiHandler extends EmptyCardUsingEventHandler<this> {

            settleHurt(n: number): Promise<void> {
                if (!this.card.cardProperties.target || !this.card.cardProperties.source || !this.card.cardProperties.owner) {
                    return super.settleHurt(n)
                }

                const gm = this.card.cardProperties.target.gameManager
                if(this.card.cardProperties.target.recoverHP(1)) {
                    gm.appendLog(this.card.cardProperties.target.name + '回复1体力')
                }

                return super.settleHurt(n)
            }
        }

        return new BaseTaoYuanJieYiHandler(card, player)
    }

    info(): string {
        return "桃园结义"
    }
}

/**
 * 五谷丰登
 */
export class WuGuFengDeng extends NoDelayBrilliantness {
    targets: Player[] = []

    candidateCards: Card[] = []

    async use(): Promise<void> {
        if (this.cardProperties.owner) {
            const gm = this.cardProperties.owner.gameManager
            this.candidateCards = gm.cardHeap.drawCards(gm.currentPlayerCount)
            const candidateInfo = this.candidateCards.map((t) => t.colorCN() + t.numberCN() + t.info()).join(',')
            gm.appendLog(this.cardProperties.owner.name + '发起' + this.info() + '候选牌有:' + candidateInfo)
            const thisCardInfo = this.colorCN() + this.numberCN() + this.info()
            gm.defineDeskCard(this.cardProperties.owner.name, thisCardInfo, '')
            this.targets = gm.presentPlayer()
            for(const target of this.targets) {
                this.cardProperties.target = target
                this.cardProperties.cancelEffect = false
                await super.use()
            }
            this.targets = []
            for(const remainedCard of this.candidateCards) {
                remainedCard.onDrop()
            }
            this.onDrop()
        }

    }

    appendDeskCard(gm: GameManager) {

    }

    async afterWuXieResponseUsing(requestWuxieHandler: CardUsingEventHandler<this>, sourceHandler: CardUsingEventHandler<this>) {
        if (this.cardProperties.target && this.cardProperties.source) {
            const handler = this.cardProperties.target.createCardUsingEventHandler(sourceHandler)
            const gm = this.cardProperties.target.gameManager
            const pickResult = await handler.pickAnyOne(this.candidateCards)
            if (pickResult.isPresent()) {
                const pickCard = pickResult.get()
                for(let i = 0; i < this.candidateCards.length; i++) {
                    if (this.candidateCards[i].equals(pickCard)) {
                        this.candidateCards.splice(i, 1)
                        break
                    }
                }
                const pickCardInfo = pickCard.colorCN() + pickCard.numberCN() + pickCard.info()
                this.cardProperties.target.handCardAreas.acquireHandCard(pickCard)
                gm.appendLog(this.cardProperties.target.name + '选取了:' + pickCardInfo)
            }

        }
    }

    info(): string {
        return "五谷丰登"
    }
}
